#define DEBUG
#include <cstdio>

using namespace std;

const int mods=1000000007, maxn=8;

long long solve_bf(int x, int y, int n, int m, int p, int q) {
  const int maxm=20/maxn+1;
  static bool matrix[maxn+1][maxm+1];
  long long ret=0;
  if (x<=n) {
    if (y<m) {
      ret = (ret+solve_bf(x, y+1, n, m, p, q))%mods;
    } else {
      ret = (solve_bf(x+1, 1, n, m, p, q)+ret)%mods;
    }
    matrix[x][y] = true;
    int temp=0;
    for (int i=y; i>y-p && i>0; i--) {
      if (matrix[x][i] && temp>=0) {
	temp++;
      } else {
	break;
      }
    }
    if (temp<p) {
      if (y<m) {
	ret = (ret+solve_bf(x, y+1, n, m, p, q))%mods;
      } else {
	ret = (solve_bf(x+1, 1, n, m, p, q)+ret)%mods;
      }
    }
    matrix[x][y] = false;
  } else {
    int temp=0;
    for (int i=1; i<=m; i++) {
      bool flag=true;
      for (int j=1; j<=n; j++) {
	if (!matrix[j][i]) {
	  flag = false;
	  break;
	}
      }
      temp += flag;
    }
    if (temp<=q) {
      ret = 1;
    } else {
      ret = 0;
    }
  }
  return ret;
}

class Matrix {
public:
  static const int maxn=70;
  int n, m;
  long long a[maxn+1][maxn+1];

  void init(int _n, int _m) {
    n = _n, m = _m;
    for (int i=0; i<n; i++) {
      for (int j=0; j<m; j++) {
	a[i][j] = 0;
      }
    }
  }

  void one() {
    for (int i=0; i<n; i++) {
      a[i][i] = 1;
    }
  }

  void copy(Matrix *x) {
    n=x->n, m=x->m;
    for (int i=0; i<n; i++) {
      for (int j=0; j<m; j++) {
	a[i][j] = x->a[i][j];
      }
    }
  }
};

void mul(Matrix *a, Matrix *b, Matrix *c) {
  c->n = a->n, c->m = b->m;
  for (int i=0; i<c->n; i++) {
    for (int j=0; j<c->m; j++) {
      c->a[i][j] = 0;
      for (int k=0; k<a->m; k++) {
	c->a[i][j] = (c->a[i][j]+a->a[i][k]*b->a[k][j]%mods)%mods;
      }
    }
  }
}

void initMat(Matrix *a, int n, int m, int p, int q) {
  a->init(1<<(n*(p-1)+2), (1<<(n*(p-1)+2)));
  for (int i=0; i<(1<<(n*(p-1))); i++) {
    for (int j=0; j<(1<<(n*(p-1))); j++) {
      if (((j>>n)&i)!=i) {
	break;
      }
      int temp=(i<<n)|j;
      bool flag=false;
      for (int k=0; k<n; k++) {
	flag = true;
	for (int l=0; l<p; l++) {
	  if (!(temp>>(k+l*n)&1)) {
	    flag = false;
	    break;
	  }
	}
	if (flag) {
	  break;
	}
      }
      if (flag) {
	continue;
      }
      for (int k=0; k<=q; k++) {
	int t=0;
	if ((j&((1<<n)-1))==((1<<n)-1)) {
	  t = 1;
	}
	if (k==q && t) {
	  continue;
	}
	a->a[i|(k<<(n*(p-1)))][j|((k+t)<<(n*(p-1)))] = 1;
      }
    }
  }
}

void powerMat(Matrix *a, int n) {
  static Matrix temp[2], s[2];
  int i=0, j=0;
  temp[0].copy(a);
  s[0].init(a->n, a->m);
  s[0].one();
  for (; n>1; n/=2) {
    if (n%2) {
      j++;
      mul(&s[(j-1)%2], &temp[i%2], &s[j%2]);
    }
    i++;
    mul(&temp[(i-1)%2], &temp[(i-1)%2], &temp[i%2]);
  }
  mul(&temp[i%2], &s[j%2], a);
}

long long solve_mat(int n, int m, int p, int q) {
  static Matrix f, t, ans;
  initMat(&f, n, m, p, q);
  powerMat(&f, m);
  t.init(1, n);
  t.a[0][0]=1;
  mul(&t, &f, &ans);
  long long ret=0;
  for (int i=0; i<n; i++) {
    ret = (ret+ans.a[0][i])%mods;
  }
  return ret;
}

int main() {
#ifdef DEBUG
  freopen("1.in", "r", stdin);
  freopen("1.out", "w", stdout);
#endif
   
  int n, m, p, q;
  scanf("%d %d %d %d", &n, &m, &p, &q);
  
  if (p==1) {
    printf("1");
  // } else if (n*m<=20) {
  //   printf("%lld", solve_bf(1, 1, n, m, p, q));
  } else {
    printf("%lld", solve_mat(n, m, p, q));
  }

  fclose(stdin);
  fclose(stdout);
  return 0;
}
